package org.robot.scm.platform.registry.strategy;

import com.google.common.collect.Lists;
import it.tdlight.jni.TdApi.GetChat;
import it.tdlight.jni.TdApi.Message;
import it.tdlight.jni.TdApi.MessageContent;
import it.tdlight.jni.TdApi.MessageSenderUser;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.robot.scm.platform.AbstractMonitor;
import org.robot.scm.platform.ReflectionLoader;
import org.robot.scm.platform.server.telegram.ScmTelegram;
import org.robot.scm.pojos.config.BaseConfig;
import org.robot.scm.pojos.enums.MessageTypeEnum;
import org.robot.scm.pojos.enums.PlatformEnum;
import org.robot.scm.pojos.platform.MessageBaseNotify;
import org.robot.scm.utils.SendNoticeHelper;
import org.robot.scm.utils.StreamUtils;

@Slf4j
public abstract class AbstractMessageHandler {

    private static final List<Integer> LAST_HASHES = Lists.newArrayList();

    @Getter
    private static final List<? extends AbstractMessageHandler> messages = ReflectionLoader.load(AbstractMessageHandler.class);

    protected abstract Class<MessageContent> clazz();

    protected abstract String doProcess(ScmTelegram scmTelegram, Message message, MessageContent messageContent);

    /**
     * 执行class类型获取
     *
     * @param clazzName
     * @return
     */
    public static AbstractMessageHandler getHandler(String clazzName) {
        return StreamUtils.filterOne(messages, m -> m.clazz().getSimpleName().equals(clazzName));
    }

    /**
     * 收到消息后处理
     */
    public static void handleMessage(ScmTelegram scmTelegram, Message message, MessageContent messageContent) {
        AbstractMessageHandler abstractMessageHandler = StreamUtils.filterOne(messages, m -> m.clazz().isInstance(messageContent));
        if (Objects.isNull(abstractMessageHandler)) {
            String sendMsg = String.format("(%s)", messageContent.getClass().getSimpleName());
            sendMessage(scmTelegram, message, sendMsg);
            return;
        }
        String sendMsg = abstractMessageHandler.doProcess(scmTelegram, message, messageContent);
        if (StringUtils.isBlank(sendMsg)) {
            return;
        }
        sendMessage(scmTelegram, message, sendMsg);
    }

    protected static void sendMessage(ScmTelegram scmTelegram, Message message, String text) {
        sendMessage(scmTelegram, message, text, MessageTypeEnum.HTML);
    }

    /**
     * 支持消息类型
     * type = markdown
     */
    protected static void sendMessage(ScmTelegram scmTelegram, Message message, String text, MessageTypeEnum messageType) {
        BaseConfig config = new BaseConfig(AbstractMonitor.mainConfig, AbstractMonitor.mainConfig.getPlatform(PlatformEnum.TELEGRAM));
        MessageSenderUser messageSenderUser = (MessageSenderUser) message.senderId;
        long chatId = message.chatId;
        AtomicReference<String> finalText = new AtomicReference<>(text);

        // Get the chat title
        scmTelegram.getClient().send(new GetChat(chatId)).whenCompleteAsync((chatIdResult, error) -> {
            if (error != null) {
                log.error("telegram receive message error", error);
                return;
            }

            try {
                // 我发的消息方向：【我】 -> 【title】
                // 别人给我的消息：【title】 -> 【我】
                // String from = messageSenderUser.userId == scmTelegram.getAdminId() ? "我" : chatIdResult.title;
                // String to = messageSenderUser.userId == scmTelegram.getAdminId() ? chatIdResult.title : "我";
                String from = handleFromName(messageSenderUser.userId == scmTelegram.getAdminId() ? "我" : chatIdResult.title);

                // 非我关注的不处理
                if (!isMeAttention(from, finalText.get())) {
                    return;
                }

                String builder = buildHtmlMessage(finalText.get());
                MessageBaseNotify notice = new MessageBaseNotify();
                notice.setMessageType(Objects.isNull(messageType) ? MessageTypeEnum.TEXT : messageType);
                notice.setMessage(Objects.equals(messageType, MessageTypeEnum.HTML) ? builder : text);
                notice.setTopic(from);

                SendNoticeHelper.sendNotice(config, notice, PlatformEnum.TELEGRAM);

                // 回复的1、好的 等不打电话
                // if (StringUtils.equals(text.trim(), "1") || StringUtils.equals(text.trim(), "好") || StringUtils.equals(text.trim(), "好的")) {
                //    return;
                // }
                // 电话通知 callVo, 有5分钟限制
                // CallHelper.callOutOf5(config, from, messageSenderUser.userId == scmTelegram.getAdminId());
            } catch (Exception e) {
                log.error("send message fail", e);
            }
        });
    }

    private static String buildHtmlMessage(String s) {
        return "<a style='text-decoration:none;color:#000'>" + s + "</a>"
                + "<br/><br/>"
                + "<a href='uniscm://' style='text-decoration:none;color:#46bc99;'>[ 执行工单 ]</a>"
                + "<br/>"
                + "<a href='tg://' style='text-decoration:none;color:#46bc99;'>[ 查看消息 ]</a>";
    }

    private static String handleFromName(String name) {
        // return StringUtils.isNotBlank(TelegramRegistry.nameMap.get(name)) ? TelegramRegistry.nameMap.get(name) : name;
        return name;
    }

    /**
     * 是否是我关注的消息
     * 非zabbix 或 是zabbix，但只关心包含 192.168.10.67、192.168.10.70、172.16.82.127、172.16.82.251
     */
    private static boolean isMeAttention(String from, String finalText) {
        // 删除前100个
        if (LAST_HASHES.size() > 100) {
            LAST_HASHES.subList(0, 100).clear();
        }
        if (StringUtils.containsIgnoreCase(finalText, "工单通知")) {
            int currentHashCode = finalText.split("\n")[0].hashCode();
            if (LAST_HASHES.contains(currentHashCode)) {
                return false;
            }
            LAST_HASHES.add(currentHashCode);
            return true;
        }
        return !StringUtils.containsIgnoreCase(from, "zabbix") &&
                !StringUtils.containsIgnoreCase(finalText, "**Firing**") &&
                !StringUtils.containsIgnoreCase(finalText, "**Resolved**") &&
                !StringUtils.equalsIgnoreCase(finalText, "已执行") &&
                !StringUtils.equals(finalText, "1");
    }

    /**
     * 目前支持txt、sql
     */
    protected static boolean isSqlFile(String fileName) {
        if (StringUtils.isBlank(fileName)) {
            return false;
        }
        fileName = fileName.toLowerCase().trim();
        return fileName.endsWith("txt") || fileName.endsWith("sql");
    }

    protected static String substring(String origin) {
        if (origin.length() < 5) {
            return origin;
        }
        if (origin.length() < 10) {
            return origin.substring(0, 3) + "***" + origin.substring(origin.length() - 3);
        }
        return origin.substring(0, 5) + "***" + origin.substring(origin.length() - 5);
    }
}
